/**
 * author:Administrator
 * date:2016/1/9
 * desc:代理管理
 *
 * 注册过来的 服务,会进行组织，然后提供服务
 */

var mgr = {};
module.exports = mgr;

mgr.add = function (urlmatch, host) {
  __addNsHost(urlmatch, host);
};

/**
 * 根据 url 选择一个server
 * @param url
 * @returns {*}
 */
mgr.getServer = function (url) {
  var nsList = Object.keys(__serverList);
  for (var urlmatch of nsList) {
    var reg = new RegExp(urlmatch, "gi");
    if (!url.match(reg)) continue;

    var matchList = __serverList[urlmatch];
    var selected = select(matchList);
    return selected;
  }
  return null;
};

mgr.CntType = {
  cntTotal: 1,
  cntSucc: 2,
  cntFail: 4,
  cntTimeout: 8
};
/**
 *
 * @param server
 * @param dTime
 * @param type 1=all,2=succ,3=fail,4=timeout
 */
mgr.reportProxyResult = function (server, dTime, type) {
  if (!server instanceof Server) {
    // TODO
  }
  server.cntTotal++;
  if (type == mgr.CntType.cntSucc) {
    server.cntSucc++;
  }
  if (type == mgr.CntType.cntFail) {
    server.cntFail++;
    server.alive = false;
    // should remove this server
  }
  if (type == mgr.CntType.cntTimeout) {
    server.cntTimeout++;
  }
  if (dTime > 0 && dTime > server.maxTimeCost)
    server.maxTimeCost = dTime;
};


function unregServer(server) {

}
mgr.printServerInfo = function (server) {
  console.log(server);
};

function select(matchList) {
  if (matchList.length == 0) return null;
  var t = null;
  for (var m of matchList) {
    if (m.alive && ( (!t) || (t && t.cntTotal > m.cntTotal) )) {
      t = m;
    }
  }
  return t;
}

var __serverList = {/* urlmatch:[host1:host2]*/};
/**
 * 新增注册
 * @param urlmatch
 * @param host
 * @private
 */
function __addNsHost(urlmatch, host) {
  if (!__serverList[urlmatch]) {
    __serverList[urlmatch] = [];
  }

  var hostList = __serverList[urlmatch];
  if (hostList.indexOf(host) < 0) hostList.push(new Server(urlmatch, host));
  __setupNewTimer(urlmatch, host);
}

function Server(urlmatch, host) {
  this.urlmatch = urlmatch;
  this.host = host;
  this.regAt = new Date();
  this.alive = true;
  this.cntTotal = 0;
  this.cntSucc = 0;
  this.cntFail = 0;
  this.cntTimeout = 0;
  this.maxTimeCost = 0;
  this.load = 1;
}

// 超时清除列表
var __serverTimer = {/*ns_host: obj*/}; // 自动删除
var __timeoutInMsec = 10 * 60 * 1000; //  60 * 1000; //

/**
 * 超时处理
 * @param urlmatch
 * @param host
 */
function __setupNewTimer(urlmatch, host) {
  var key = urlmatch + '_' + host;
  var timer = __serverTimer[key];
  if (timer) {
    console.log('reset %s,key=%s', urlmatch, key);
    timer.reset();
    return;
  }
  /* create new timer */
  timer = new AutoCleanTimer(urlmatch, host);
  __serverTimer[key] = timer;
  timer.start();
}
/**
 * @param urlmatch
 * @param host
 * @constructor
 */
function AutoCleanTimer(urlmatch, host) {
  this.urlmatch = urlmatch;
  this.host = host;
}

AutoCleanTimer.prototype.start = function () {
  var self = this;
  this.timer = setTimeout(function () {
    self.timeout();
  }, __timeoutInMsec);
};

AutoCleanTimer.prototype.timeout = function () {
  console.log('server timeout: %s-%s', this.urlmatch, this.host);
  var thisKey = this.urlmatch + '_' + this.host;
  var list = __serverList[this.urlmatch];

  // remove the host
  var i = 0, len = list.length;
  for (; i < len; i++) {
    if (list[i].host === this.host) {
      break;
    }
  }
  if (i < len) list.splice(i, 1);

  // remove timer
  delete __serverTimer[thisKey];
};

AutoCleanTimer.prototype.reset = function () {
  clearTimeout(this.timer);
  this.start();
};
